<?php

namespace App\Http\Controllers\Wechat;

use App\Models\AnswerActivity;
use App\Models\AnswerActivityLimitAddress;
use App\Models\AnswerActivityProblem;
use App\Models\AnswerActivityUnit;
use App\Models\AnswerActivityUserAnswerRecord;
use App\Models\AnswerActivityUserCorrectTotalNumber;
use App\Models\AnswerActivityUserPrize;
use App\Validate\AnswerActivityAnswerValidate;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * 活动答题管理
 */
class AnswerActivityAnswerController extends CommonController
{

    public $model = null;
    public $activityModel = null;
    public $validate = null;


    public function __construct()
    {
        parent::__construct();

        $this->model = new AnswerActivityUserAnswerRecord();
        $this->activityModel = new AnswerActivity();
        $this->validate = new AnswerActivityAnswerValidate();
    }

    /**
     * 开始答题（获取题目信息）
     * @param timestamp  时间戳  13位
     * @param sign  签名  token 拼接 sign_key 拼接 时间戳  然后  md5后值 在全部转大写的值
     * @param token  用户guid
     * @param act_id int 活动id
     * @param unit_id int 单位id  除独立活动外，都是必填
     * 
     * @param lon 经度
     * @param lat 纬度
     */
    public function getAnswerProblem()
    {
        //   Log::error($this->request->all());die;
        //增加验证场景进行验证
        if (!$this->validate->scene('get_answer_problem')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        //判断经纬度是否符合参赛要求
        if (empty($this->request->lon) || empty($this->request->lat)) {
            return $this->returnApi(211, "请开启手机定位功能");
        }
        $answerActivityLimitAddressModel = new AnswerActivityLimitAddress();
        $lon_lat_info = $answerActivityLimitAddressModel->checkLonLat($this->request->act_id, $this->request->lon, $this->request->lat);
        if ($lon_lat_info !== true) {
            return $this->returnApi(210, "您当前位置不在活动范围");
        }

        //验证签名是否正确
        if (!$this->verifySignature($this->request->timestamp, $this->request->token, $this->request->sign)) {
            return $this->returnApi(201, '签名错误');
        }

        $act_info = $this->activityModel->detail($this->request->act_id);

        if (empty($act_info)) {
            return $this->returnApi(201, '参数错误');
        }

        //是否自动重置数据
        if ($act_info['is_reset_data'] == 1 && $act_info['answer_start_time'] < date('Y-m-d H:i:s')) {
            $this->activityModel->resetData($this->request->act_id, $act_info['answer_start_time']);
            $this->activityModel->where('id', $this->request->act_id)->update(['is_reset_data' => 2]); //自动改为不可重置状态
        }

        // 判断 今日上一次是否主动提交，没有需要手动提交一次 ,只处理轮次排名
        if ($act_info['pattern'] == 2) {
            $activityUserCorrectTotalNumber = new AnswerActivityUserCorrectTotalNumber();
            $activityUserCorrectTotalNumber->lastCorrectGuestPosting($act_info['id'], $this->request->token, $act_info['answer_time'], $act_info['answer_number'], $act_info['node']);
        }


        if ($act_info['node'] != 1 && empty($this->request->unit_id)) {
            return $this->returnApi(201, '单位id不能为空');
        }

        if ($act_info['node'] == 1 && !empty($this->request->unit_id)) {
            return $this->returnApi(201, '此活动为独立活动，不允许选择单位');
        }

        if ($act_info['node'] == 1) {
            $this->request->unit_id = 0; //重置为 1 
        }


        //活动状态 //活动状态 1 活动未开始 2.答题未开始 3.进行中 4.答题已结束  5 活动已结束 
        $status = $this->activityModel->isCanAnswer($act_info, $this->request->token);
        if ($status !== true) {
            return $this->returnApi(201,  $status);
        }
        //判断今日答题次数是否还有
        $day_answer_number = $this->model->surplusAnswerNumber($this->request->token, $act_info['id'], $act_info['number'], $act_info['share_number']);
        if ($day_answer_number <= 0) {
            $is_end_time = $this->activityModel->isEndTime($act_info['answer_end_time']);
            return $this->returnApi(201,  '今日答题次数已用完,' . $is_end_time);
        }
        //获取单位答题次数
        $is_have_surplus_unit_answer_number = $this->model->isHaveSurplusUnitAnswerNumber($this->request->token, $this->request->act_id, $this->request->unit_id, $act_info);

        if ($is_have_surplus_unit_answer_number !== true) {
            return $this->returnApi(201,  $is_have_surplus_unit_answer_number);
        }

        //获取题目
        DB::beginTransaction();
        try {
            $activityProblemModel = new AnswerActivityProblem();

            $res = $activityProblemModel->getProblem($this->request->token, $this->request->act_id, $this->request->unit_id, $act_info);
            if (empty($res)) {
                throw new Exception('获取题目失败，此次答题不消耗次数，请稍后重试');
            }

            $data = [];
            //获取单位答题次数 如果是轮次答题，就是轮次次数
            $activityUnitModel = new AnswerActivityUnit();
            $user_answer_number = $activityUnitModel->unitAnswerNumber($act_info['pattern'], $this->request->token, $this->request->act_id, $this->request->unit_id);

            // Log::error([$act_info['pattern'], $this->request->token, $this->request->act_id, $this->request->unit_id]);
            // Log::error($user_answer_number);

            // dump($user_answer_number);
            $user_answer_number = $user_answer_number ?: 0;

            //获取现有抽奖钥匙个数
            $activityUserPrizeModel = new AnswerActivityUserPrize();
            $key_number = $activityUserPrizeModel->getUserPrizeNumber($act_info['id'], $this->request->token);
            $data['user_info']['key_number'] = empty($key_number) ? 0 : $key_number['number'] - $key_number['use_number'];

            //今日剩余答题次数
            $activityUserAnswerRecordModel = new AnswerActivityUserAnswerRecord();
            $data['user_info']['surplus_answer_number'] = $activityUserAnswerRecordModel->surplusAnswerNumber($this->request->token, $this->request->act_id, $act_info['number'], $act_info['share_number']);


            $data['total_floor'] = $act_info['total_floor']; //爬楼梯梯模式，总楼层
            $data['answer_number'] = $act_info['answer_number'];
            $data['user_answer_number'] = $act_info['is_loop'] == 1 ? $user_answer_number % $act_info['answer_number'] : $user_answer_number;

            $data['answer_time'] = $act_info['answer_time']; //答题时间


            foreach ($res as $key => $val) {
                unset($res[$key]['act_id'], $res[$key]['unit_id']);

                if ($val['type'] == 2) {
                    unset($res[$key]['con_answer']);
                } else {
                    foreach ($val['con_answer'] as $k => $v) {
                        $res[$key]['con_answer'][$k]['serial'] =  serial_letter($k + 1);
                    }
                }
            }
            $data['problem'] = $res; //答题

            DB::commit();
            return $this->returnApi(200, '获取成功', true, $data);
        } catch (\Exception $e) {
            Log::error($e->getMessage() . $e->getFile() . $e->getLine());
            DB::rollBack();
            return $this->returnApi(202, $e->getMessage());
        }
    }


    /**
     * 用户答题 
     * @param timestamp  时间戳  13位
     * @param sign  签名  token 拼接 sign_key 拼接 时间戳  然后  md5后值 在全部转大写的值
     * @param token  用户guid
     * @param act_id  int 活动id
     * @param answer  答案  json格式 
     *
     * 
     *    answer    json格式 ： [{"guid":"1111111111","answer_id":1,"content":"\u586b\u7a7a\u9898\u7b54\u6848"}]
     *               数组格式 ： [['guid'=>'1111111111' , 'answer_id'=>1 , 'content'=>'填空题答案']]；
     * 
     *    @param answer_id  int 选择题答案id     与content二选一
     *    @param content  string 填空题答案
     *    @param guid  string 问题guid  必传
     */
    public function replyProblem()
    {
        //   Log::error($this->request->all());

        //增加验证场景进行验证
        if (!$this->validate->scene('reply_problem')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }
        //验证签名是否正确
        if (!$this->verifySignature($this->request->timestamp, $this->request->token, $this->request->sign)) {
            return $this->returnApi(201, '签名错误');
        }

        $act_info = $this->activityModel->detail($this->request->act_id);

        if (empty($act_info)) {
            return $this->returnApi(201, '参数错误');
        }
        //查看此题是否已经回复过
        DB::beginTransaction();
        try {
            $activityProblemModel = new AnswerActivityProblem();

            $res = $activityProblemModel->replyProblem($this->request->token, $this->request->answer, $act_info);

            if (empty($res)) {
                throw new Exception('网络错误');
            }

            //获取单位答题次数 如果是轮次答题，就是轮次次数
            $activityUnitModel = new AnswerActivityUnit();
            $user_answer_number = $activityUnitModel->unitAnswerNumber($act_info['pattern'], $this->request->token, $act_info['id'], $res['unit_id']);

            $user_answer_number = $user_answer_number ?: 0;

            //今日剩余答题次数
            $activityUserAnswerRecordModel = new AnswerActivityUserAnswerRecord();
            $surplus_answer_number = $activityUserAnswerRecordModel->surplusAnswerNumber($this->request->token, $this->request->act_id, $act_info['number'], $act_info['share_number']);


            //馆内答题   答题进度：  1/5      爬楼梯：答题进度 52/100        轮次：已答轮次：5轮   
            $total_floor = $act_info['total_floor']; //爬楼梯模式，总楼层  
            $answer_number = $act_info['answer_number'];
            $user_answer_number = $act_info['is_loop'] == 1 ? $user_answer_number % $act_info['answer_number'] : $user_answer_number;

            if ($act_info['pattern'] == 2) {
                $accuracy = $res['success'] + $res['error'] == 0 || $res['success'] == 0 ? 0 : $res['success'] / ($res['success'] + $res['error']);
                $accuracy = sprintf("%.2f", $accuracy * 100);

                $data = [
                    'pattern' => $act_info['pattern'],
                    'problem_answer' => null,
                    'status' => null,
                    'success' => $res['success'],
                    'error' => $res['error'],
                    'accuracy' => $accuracy,
                    'total_floor' => $total_floor,
                    'answer_number' => $answer_number,
                    'user_answer_number' => $user_answer_number,
                    'surplus_answer_number' => $surplus_answer_number,
                    'is_get_prize' => $res['is_get_prize'], //是否获取钥匙
                ];
            } else {
                $data = [
                    'pattern' => $act_info['pattern'],
                    'problem_answer' => [
                        'is_show_analysis' => $res['problem_answer']['is_show_analysis'] == 1 && !empty($res['problem_answer']['analysis']) ? 1 : 2,
                        'analysis' => $res['problem_answer']['is_show_analysis'] == 1 ? $res['problem_answer']['analysis'] : null,
                        'success_answer' => $res['problem_answer']['is_show_analysis'] == 1 ? $res['problem_answer']['con_answer'][0]['content'] : null,
                    ],
                    'status' => $res['status'],
                    'success' => $res['status'] == 1 ? 1 : 0,
                    'error' => $res['status'] == 1 ? 0 : 1,
                    'accuracy' => $res['status'] == 1 ? '100%' : 0,
                    'total_floor' => $total_floor,
                    'answer_number' => $answer_number,
                    'user_answer_number' => $user_answer_number,
                    'surplus_answer_number' => $surplus_answer_number,
                    'is_get_prize' => $res['is_get_prize'], //是否获取钥匙
                ];
            }

            DB::commit();
            return $this->returnApi(200, '答题成功', true, $data);
        } catch (\Exception $e) {
            Log::error($e->getMessage() . $e->getFile() . $e->getLine());
            DB::rollBack();
            return $this->returnApi(202, $e->getMessage());
        }
    }
}
